#include <sea_common>
#include "test_associations.h"

// -------------------------------------------------------------------------------------------------

/*
    shape
    color
    living
    !living
    taste
    size
    proximity
    similarity
*/

class Parent: public sea::Object { };
class Child: public sea::Object { };

// -------------------------------------------------------------------------------------------------

void test_associations( )
{
    {
        aref a( "1" );
        aref b( "2" );
        
        a += b;
        a -= b;
        
        aref c( "3" );
        c << c;
    }
    SEA_MEM_LEAKS( );

    {
        aref p; p << NEW Parent( );
        aref c; c << NEW Child( );
        
        p += c;
        p -= c;
    }
    SEA_MEM_LEAKS( );

    {
        aref shape( "shape" );

            aref round( "round" );
            aref square( "square" );
            aref triangle( "triangle" );

        aref color( "color" );
            aref red( "red" );
            aref yellow( "yellow" );
            aref blue( "blue" );

        aref living( "living" );
        aref n_living( "n_living" );

        aref gender( "gender" );
            aref male( "male" );
            aref female( "female" );
            
        aref taste( "taste" );
            aref sweet( "sweet" );

        aref size( "size" );
            aref s_big( "big" );
            aref s_small( "small" );
            
        aref proximity( "proximity" );
            aref p_far( "far" );
            aref p_close( "close" );
            aref in_cmeters( "in_cmeters" );
            aref in_meters( "in_meters" );
            aref in_kmeters( "in_kmeters" );
            aref in_inches( "in_inches" );
            aref in_miles( "in_miles" );

        aref similarity( "similarity" );

        aref temperature( "temperature" );
            aref high( "high" );
            aref low( "low" );
            aref in_C( "in_C" );
            aref in_F( "in_F" );

        aref eatable( "eatable" );
        aref n_eatable( "n_eatable" );

        aref ownership( "ownership" );
            aref part_of( "part_of" );          // child
            aref consists_of( "consists_of" );  // parent
    }
    SEA_MEM_LEAKS( );

    {
        void ass( );
        ass( );
    }
    SEA_MEM_LEAKS( );
}

// -------------------------------------------------------------------------------------------------

void ass( )
{
    // An object
    aref apple( "apple" );
    
    // Objects qualities
    aref color( "color" );
    aref smell( "smell" );

    // More quality details
    aref red( "red" );

    // Red is a color
    red += color; // Or red->is( color );

    // List colors
    for( sea::VIterator< sea::Object, sea::Either > it( color ); *it; it++ )
    {
        SEA_TRACE( " Color has %s", it->as< char >( ) );
    }

    // Adding apple attributes
    apple += color; // OR apple->has( color );
    apple += smell; // Or apple->has( smell );

    if ( apple( color ) && apple( smell ) )
    {
        SEA_TRACE( "Apple has color & smell" );
    }

    // List them
    for( sea::VIterator< sea::Object, sea::Either > it( apple ); *it; it++ )
    {
        SEA_TRACE( " %s has %s", apple->as< char >( ), it->as< char >( ) );
    }

    // Break the associations. Apple doesnt smell or has no color
    apple -= color; // OR apple->has_no( color );
    apple -= smell; // OR apple->has_no( smell );

    if ( !apple( color ) && !apple( smell ) )
    {
        SEA_TRACE( "Apple has no color or smell" );
    }

    // Remove all attributes/associations
    color->detach_all( );
}

// -------------------------------------------------------------------------------------------------